<!DOCTYPE html>
<html lang="zh-Hans">

<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="x5-fullscreen" content="true">
<meta name="full-screen" content="yes">
<meta name="theme-color" content="#317EFB" />
<meta content="width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=0" name="viewport">
<meta name="description" content="1.1 集合1.1.1 List：可重复1.ArrayList： 数组实现，增删慢，查询快，线程不安全2.Vector： 数组实现，增删慢，查询快，线程安全3.LinkedList： 双向链表实现，增删快，查询慢，线程不安全 相关面试题（1）.ArrayList和LinkedList有什么区别？⭐⭐⭐我的认识：首先，ArrayList是数组实现的，增删慢，查询快，是通过索引查询，并且ArrayLi">
<meta property="og:type" content="article">
<meta property="og:title" content="Java 基础">
<meta property="og:url" content="https://big-ttong/myblog.git/2023/08/01/Java%E5%9F%BA%E7%A1%80/index.html">
<meta property="og:site_name" content="欢迎访问我的blog">
<meta property="og:description" content="1.1 集合1.1.1 List：可重复1.ArrayList： 数组实现，增删慢，查询快，线程不安全2.Vector： 数组实现，增删慢，查询快，线程安全3.LinkedList： 双向链表实现，增删快，查询慢，线程不安全 相关面试题（1）.ArrayList和LinkedList有什么区别？⭐⭐⭐我的认识：首先，ArrayList是数组实现的，增删慢，查询快，是通过索引查询，并且ArrayLi">
<meta property="og:locale">
<meta property="article:published_time" content="2023-08-01T00:34:01.633Z">
<meta property="article:modified_time" content="2023-08-01T00:42:02.973Z">
<meta property="article:author" content="洪汉桐">
<meta name="twitter:card" content="summary">


<title >Java 基础</title>

<!-- Favicon -->

    <link href='/myblog/log.svg?v=2.0.9' rel='icon' type='image/png' sizes='16x16' ></link>


    <link href='/myblog/log.svg?v=2.0.9' rel='icon' type='image/png' sizes='32x32' ></link>


    <link href='/myblog/log.svg?v=2.0.9' rel='apple-touch-icon' sizes='180x180' ></link>


    <link href='/myblog/site.webmanifest' rel='manifest' ></link>


<!-- Plugin -->




    
<link rel="stylesheet" href="/myblog/css/plugins/bootstrap.row.css">

    
<link rel="stylesheet" href="https://unpkg.com/locomotive-scroll@4.1.4/dist/locomotive-scroll.min.css">

    
<link rel="stylesheet" href="https://unpkg.com/@fancyapps/ui@4.0/dist/fancybox.css">

    
    




<!-- Icon -->

    
<link rel="stylesheet" href="/myblog/css/plugins/font-awesome.min.css">




<!-- Variable -->
<script>window.ASYNC_CONFIG = {"hostname":"big-ttong","author":"洪汉桐","root":"/myblog/","typed_text":["extraordinary"],"theme_version":"2.0.9","theme":{"switch":true,"default":"style-light"},"favicon":{"logo":"log.svg","icon16":"log.svg","icon32":"log.svg","appleTouchIcon":"log.svg","webmanifest":"/site.webmanifest","visibilitychange":true,"hidden":"failure.ico","showText":"(/≧▽≦/)咦！又好了！","hideText":"(●—●)喔哟，崩溃啦！"},"i18n":{"placeholder":"搜索文章...","empty":"找不到您查询的内容: ${query}","hits":"找到 ${hits} 条结果","hits_time":"找到 ${hits} 条结果（用时 ${time} 毫秒）","author":"本文作者：","copyright_link":"本文链接：","copyright_license_title":"版权声明：","copyright_license_content":"本博客所有文章除特别声明外，均默认采用 undefined 许可协议。","copy_success":"复制成功","copy_failure":"复制失败","open_read_mode":"进入阅读模式","exit_read_mode":"退出阅读模式","notice_outdate_message":"距离上次更新已经 undefined 天了, 文章内容可能已经过时。","just":"刚刚","min":"分钟前","hour":"小时前","day":"天前","month":"个月前"},"swup":false,"plugin":{"flickr_justified_gallery":"https://unpkg.com/flickr-justified-gallery@latest/dist/fjGallery.min.js"},"icons":{"sun":"far fa-sun","moon":"far fa-moon","play":"fas fa-play","email":"far fa-envelope","next":"fas fa-arrow-right","calendar":"far fa-calendar-alt","clock":"far fa-clock","user":"far fa-user","back_top":"fas fa-arrow-up","close":"fas fa-times","search":"fas fa-search","reward":"fas fa-hand-holding-usd","user_tag":"fas fa-user-alt","toc_tag":"fas fa-th-list","read":"fas fa-book-reader","arrows":"fas fa-arrows-alt-h","double_arrows":"fas fa-angle-double-down","copy":"fas fa-copy"},"icontype":"font","highlight":{"plugin":"highlighjs","theme":true,"copy":true,"lang":true,"title":"default","height_limit":200},"notice_outdate":{"enable":true,"style":"flat","limit_day":365,"position":"top"}};</script>
<script id="async-page-config">window.PAGE_CONFIG = {"isPost":true,"isHome":false,"postUpdate":"2023-08-01 08:42:02"};</script>

<!-- Theme mode css -->
<link data-swup-theme rel="stylesheet" href="/myblog/css/index.css?v=2.0.9" id="trm-switch-style">
<script>
    let defaultMode = ASYNC_CONFIG.theme.default !=='auto' ?  ASYNC_CONFIG.theme.default : (window.matchMedia("(prefers-color-scheme: light)").matches ? 'style-light' : 'style-dark')
    let catchMode = localStorage.getItem('theme-mode') || defaultMode;
    let type = catchMode === 'style-dark' ? 'add' : 'remove';
    document.documentElement.classList[type]('dark')
</script>

<!-- CDN -->


    
    



<!-- Site Analytics -->
 
<meta name="generator" content="Hexo 6.3.0"></head>

<body>

  <!-- app wrapper -->
  <div class="trm-app-frame">

    <!-- page preloader -->
    <div class="trm-preloader">
    <div class="trm-holder">
        <div class="preloader">
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </div>
    </div>
</div>
    <!-- page preloader end -->

    <!-- change mode preloader -->
    <div class="trm-mode-swich-animation-frame">
    <div class="trm-mode-swich-animation">
        <i class="i-sun"><i class="iconfont far fa-sun"></i></i>
        <div class="trm-horizon"></div>
        <i class="i-moon"><i class="iconfont far fa-moon"></i></i>
    </div>
</div>
    <!-- change mode preloader end -->

      <!-- scroll container -->
      <div id="trm-dynamic-content" class="trm-swup-animation">
        <div id="trm-scroll-container" class="trm-scroll-container" data-scroll-container style="opacity: 0">
          <div data-scroll-section id="content" class="trm-scroll-section">

            <div class="locomotive-scroll__sticky-target" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; pointer-events: none;"></div>

            <!-- top bar -->
            <header class="trm-top-bar" data-scroll data-scroll-sticky data-scroll-target=".locomotive-scroll__sticky-target" data-scroll-offset="-10">
	<div class="container">
		<div class="trm-left-side">
			<!-- logo -->
<a href="/myblog/" class="trm-logo-frame trm-anima-link">
    
        <img alt="logo" src="/myblog/log.svg">
    
    
        <div class="trm-logo-text">
            洪<span>汉桐</span>
        </div>
    
</a>
<!-- logo end -->
		</div>
		<div class="trm-right-side">
			<!-- menu -->
<div class="trm-menu">
    <nav>
        <ul>
            
            <li class="menu-item-has-children ">
                <a  href="/myblog/" target="">
                    首页
                </a>
                
            </li>
            
            <li class="menu-item-has-children ">
                <a  href="/myblog/archives/" target="">
                    归档
                </a>
                
            </li>
            
        </ul>
    </nav>
</div>
<!-- menu end -->
			
    <!-- mode switcher place -->
    <div class="trm-mode-switcher-place">
        <div class="trm-mode-switcher">
            <i class="iconfont far fa-sun"></i>
            <input class="tgl tgl-light" id="trm-swich" type="checkbox">
            <label class="trm-swich" for="trm-swich"></label>
            <i class="iconfont far fa-moon"></i>
        </div>
    </div>
    <!-- mode switcher place end -->

			
		</div>
		<div class="trm-menu-btn">
			<span></span>
		</div>
	</div>
</header>
            <!-- top bar end -->

            <!-- body -->
            
<div class="trm-content-start">
    <!-- banner -->
    <div class="trm-banner" data-scroll data-scroll-direction="vertical">
    
    <!-- banner cover -->
    <img style="object-position:top;object-fit:cover;" alt="banner" class="trm-banner-cover" data-scroll data-scroll-direction="vertical" data-scroll-speed="-3" src="/myblog/img/banner.png">
    <!-- banner cover end -->
    

    <!-- banner content -->
    <div class="trm-banner-content trm-overlay">
        <div class="container" data-scroll data-scroll-direction="vertical" data-scroll-speed="0">
            <div class="row">
                
                <div class="col-lg-4"></div>
                
                <div class="col-lg-8">

                    <!-- banner title -->
                    <div class="trm-banner-text ">
                        <div class="trm-label trm-mb-20">
                            NEWS LETTER
                        </div>
                        <h1 class="trm-mb-30 trm-hsmb-font">
                            Java 基础
                        </h1>

                        
                            <ul class="trm-breadcrumbs trm-label">
                                <li>
                                    <a href="/myblog/" class="trm-anima-link">Home</a>
                                </li>
                                <li>
                                    <span>
                                        2023
                                    </span
                                ></li>
                            </ul>
                        
                    </div>
                    <!-- banner title end -->

                    <!-- scroll hint -->
                    <a href="#about-triger" data-scroll-to="#about-triger" data-scroll-offset="-130" class="trm-scroll-hint-frame">
                        <div class="trm-scroll-hint"></div>
                        <span class="trm-label">Scroll down</span>
                    </a>
                    <!-- scroll hint end -->

                </div>
            </div>
        </div>
    </div>
    <!-- banner content end -->
</div>
    <!-- banner end -->
    <div class="container">
        <div class="row">
            
                <div id="page-sidebar" class="col-lg-4 hidden-sm">
                    <!-- main card -->
                    

<div class="trm-main-card-frame trm-sidebar">
    <div class="trm-main-card" data-scroll data-scroll-repeat data-scroll-sticky data-scroll-target=".locomotive-scroll__sticky-target" data-scroll-offset="60"> 
    
        <div class="trm-user-tabs" id="sidebar-tabs">
           <div class="trm-tabs-nav trm-mb-40" id="trm-tabs-nav">
                <div data-to="tabs-user" class="trm-tabs-nav-item">
                    <i class="iconfont fas fa-user-alt"></i>
                </div>
                <div data-to="tabs-toc" class="trm-tabs-nav-item active">
                    <i class="iconfont fas fa-th-list"></i>
                </div>
           </div>
            <div name="tabs-user" class="trm-tabs-item">
                <!-- card header -->
<div class="trm-mc-header">
    <div class="trm-avatar-frame trm-mb-20">
        <img alt="Avatar" class="trm-avatar trm-light-icon" src="/myblog/img/profilephoto2.jpg"> <img alt="Avatar" class="trm-avatar trm-dark-icon" src="/myblog/img/profilephoto1.jpg">
    </div>
    <h5 class="trm-name trm-mb-15">
        洪汉桐
    </h5>
    
        <div class="trm-label">
            I`m
            <span class="trm-typed-text">
                <!-- Words for theme.user.typedText -->
            </span>
        </div>
    
</div>
<!-- card header end -->
                <!-- sidebar social -->

<div class="trm-divider trm-mb-40 trm-mt-40"></div>
<div class="trm-social">
    
        <a href="https://github.com" title="Github" rel="nofollow" target="_blank">
            <i class="iconfont fab fa-github"></i>
        </a>
    
</div>

<!-- sidebar social end -->
                <!-- info -->
<div class="trm-divider trm-mb-40 trm-mt-40"></div>
<ul class="trm-table trm-mb-20">
    
        <li>
            <div class="trm-label">
                地址:
            </div>
            <div class="trm-label trm-label-light">
                河北雄安
            </div>
        </li>
    
        <li>
            <div class="trm-label">
                年龄:
            </div>
            <div class="trm-label trm-label-light">
                19
            </div>
        </li>
    
</ul>
<!-- info end -->

                
    <div class="trm-divider trm-mb-40 trm-mt-40"></div>
    <!-- action button -->
    <div class="text-center">
        <a href="mailto:2067046599@qq.com" class="trm-btn">
            联系我
            <i class="iconfont far fa-envelope"></i>
        </a>
    </div>
    <!-- action button end -->

            </div>
            <div name="tabs-toc" class="trm-tabs-item active">
                <div class="post-toc">
    <ol class="toc"><li class="toc-item toc-level-1"><a rel="nofollow" class="toc-link" href="#1-1-集合"  data-scroll-to="#1-1-集合"><span class="toc-number">1.</span> <span class="toc-text">1.1 集合</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-1-1-List：可重复"  data-scroll-to="#1-1-1-List：可重复"><span class="toc-number">1.1.</span> <span class="toc-text">1.1.1 List：可重复</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#相关面试题"  data-scroll-to="#相关面试题"><span class="toc-number">1.1.1.</span> <span class="toc-text">相关面试题</span></a></li></ol></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-1-2-Queue"  data-scroll-to="#1-1-2-Queue"><span class="toc-number">1.2.</span> <span class="toc-text">1.1.2 Queue</span></a></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-1-3-Set-不可重复"  data-scroll-to="#1-1-3-Set-不可重复"><span class="toc-number">1.3.</span> <span class="toc-text">1.1.3 Set 不可重复</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#相关面试题-1"  data-scroll-to="#相关面试题-1"><span class="toc-number">1.3.1.</span> <span class="toc-text">相关面试题</span></a></li></ol></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-1-4-Map"  data-scroll-to="#1-1-4-Map"><span class="toc-number">1.4.</span> <span class="toc-text">1.1.4 Map</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#相关面试题-2"  data-scroll-to="#相关面试题-2"><span class="toc-number">1.4.1.</span> <span class="toc-text">相关面试题</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a rel="nofollow" class="toc-link" href="#1-2-异常的分类及处理"  data-scroll-to="#1-2-异常的分类及处理"><span class="toc-number">2.</span> <span class="toc-text">1.2 异常的分类及处理</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-2-1-异常的概念"  data-scroll-to="#1-2-1-异常的概念"><span class="toc-number">2.1.</span> <span class="toc-text">1.2.1 异常的概念</span></a></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-2-2-异常的分类"  data-scroll-to="#1-2-2-异常的分类"><span class="toc-number">2.2.</span> <span class="toc-text">1.2.2 异常的分类</span></a></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-2-3-处理异常的方式"  data-scroll-to="#1-2-3-处理异常的方式"><span class="toc-number">2.3.</span> <span class="toc-text">1.2.3 处理异常的方式</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#相关面试题-3"  data-scroll-to="#相关面试题-3"><span class="toc-number">2.3.1.</span> <span class="toc-text">相关面试题</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a rel="nofollow" class="toc-link" href="#1-3-反射机制"  data-scroll-to="#1-3-反射机制"><span class="toc-number">3.</span> <span class="toc-text">1.3 反射机制</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-3-1-动态语言的概念"  data-scroll-to="#1-3-1-动态语言的概念"><span class="toc-number">3.1.</span> <span class="toc-text">1.3.1 动态语言的概念</span></a></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-3-2-反射机制的概念"  data-scroll-to="#1-3-2-反射机制的概念"><span class="toc-number">3.2.</span> <span class="toc-text">1.3.2 反射机制的概念</span></a></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-3-3-反射的应用"  data-scroll-to="#1-3-3-反射的应用"><span class="toc-number">3.3.</span> <span class="toc-text">1.3.3 反射的应用</span></a></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-3-4-Java的反射API"  data-scroll-to="#1-3-4-Java的反射API"><span class="toc-number">3.4.</span> <span class="toc-text">1.3.4 Java的反射API</span></a></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-3-5-反射的过程"  data-scroll-to="#1-3-5-反射的过程"><span class="toc-number">3.5.</span> <span class="toc-text">1.3.5 反射的过程</span></a></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-3-6-创建对象的两种方式"  data-scroll-to="#1-3-6-创建对象的两种方式"><span class="toc-number">3.6.</span> <span class="toc-text">1.3.6 创建对象的两种方式</span></a></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-3-7-Method的invoke方法"  data-scroll-to="#1-3-7-Method的invoke方法"><span class="toc-number">3.7.</span> <span class="toc-text">1.3.7 Method的invoke方法</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#相关面试题-4"  data-scroll-to="#相关面试题-4"><span class="toc-number">3.7.1.</span> <span class="toc-text">相关面试题</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a rel="nofollow" class="toc-link" href="#1-4-注解"  data-scroll-to="#1-4-注解"><span class="toc-number">4.</span> <span class="toc-text">1.4 注解</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-4-1-注解的概念"  data-scroll-to="#1-4-1-注解的概念"><span class="toc-number">4.1.</span> <span class="toc-text">1.4.1 注解的概念</span></a></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-4-2-标准元注解：-Target、-Retention、-Documented、-Inherited"  data-scroll-to="#1-4-2-标准元注解：-Target、-Retention、-Documented、-Inherited"><span class="toc-number">4.2.</span> <span class="toc-text">1.4.2 标准元注解：@Target、@Retention、@Documented、@Inherited</span></a></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#1-4-3-注解处理器"  data-scroll-to="#1-4-3-注解处理器"><span class="toc-number">4.3.</span> <span class="toc-text">1.4.3 注解处理器</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#相关面试题-5"  data-scroll-to="#相关面试题-5"><span class="toc-number">4.3.1.</span> <span class="toc-text">相关面试题</span></a></li></ol></li></ol></li></ol>
</div>
            </div>
        </div>
    
    </div>
</div>
                    <!-- main card end -->
                </div>
            
            <div id="page-content" class="col-lg-8">
                <div class="trm-content" id="trm-content">
                    <div data-scroll data-scroll-repeat data-scroll-offset="500" id="about-triger"></div>

                    <div id="post-info" class="row hidden-sm">
    <div class="col-sm-4">
        <div class="trm-card trm-label trm-label-light text-center">
            <i class="iconfont far fa-calendar-alt trm-icon"></i><br>
            08/01
        </div>
    </div>
    <div class="col-sm-4">
        <div class="trm-card trm-label trm-label-light text-center">
            <i class="iconfont far fa-clock trm-icon"></i><br>
            08:34
        </div>
    </div>
    <div class="col-sm-4">
        <div id="post-author" class="trm-card trm-label trm-label-light text-center">
            <i class="iconfont far fa-user trm-icon"></i><br>
            洪汉桐
        </div>
    </div>
</div>
<div class="trm-card ">
    <article id="article-container" class="trm-publication">
    <h1 id="1-1-集合"><a href="#1-1-集合" class="headerlink" title="1.1 集合"></a>1.1 集合</h1><h2 id="1-1-1-List：可重复"><a href="#1-1-1-List：可重复" class="headerlink" title="1.1.1 List：可重复"></a>1.1.1 List：可重复</h2><p>1.ArrayList： 数组实现，增删慢，查询快，线程不安全<br>2.Vector： 数组实现，增删慢，查询快，线程安全<br>3.LinkedList： 双向链表实现，增删快，查询慢，线程不安全</p>
<h3 id="相关面试题"><a href="#相关面试题" class="headerlink" title="相关面试题"></a>相关面试题</h3><p>（1）.ArrayList和LinkedList有什么区别？⭐⭐⭐<br>我的认识：<br>首先，ArrayList是数组实现的，增删慢，查询快，是通过索引查询，并且ArrayList里的值有固定大小，需要提前定义好，且需要移动元素，所以增删是比较慢的。<br>然后就是LinkedList，它是双向链表实现的，增删快，查询慢，查询是要经过从头到尾的遍历，效率低。而增删通过链表实现，只需要将指针移动就可以实现增加和删除，效率高，而且LinkedList没有固定大小，可以随时添加数据。</p>
<p>答案搜集：<br>ArrayList和LinkedList是Java中两种常见的集合类，它们都实现了List接口，但在内部实现上有一些区别。<br>底层数据结构: ArrayList使用动态数组作为底层数据结构，而LinkedList使用双向链表作为底层数据结构。这导致它们在插入、删除和随机访问元素时的性能差异。<br>随机访问: ArrayList支持高效的随机访问，因为它内部使用数组实现，可以通过索引直接访问元素。而LinkedList在随机访问时需要遍历链表，因此效率较低。<br>插入和删除: LinkedList在插入和删除元素时比ArrayList更高效。在LinkedList中，插入和删除操作只需要调整链表中的指针，不需要移动其他元素。而ArrayList在插入和删除元素时，需要将后面的元素进行移动。<br>内存消耗: LinkedList相对于ArrayList需要更多的内存空间。因为LinkedList除了存储元素本身外，还需要存储每个元素的前后指针。</p>
<p>（2）.对List集合去重都有哪些方法？   ⭐⭐⭐<br>1.使用set，将List转为set</p>
<p>补充：<br>    在Java中，可以使用以下几种方法对List集合进行去重：</p>
<p>使用Set集合: 将List集合转换为Set集合，因为Set集合不允许重复元素，所以重复的元素会被自动去除。可以使用以下代码进行转换：</p>
<p>List<String> list &#x3D; new ArrayList&lt;&gt;();<br>&#x2F;&#x2F; 添加元素到list…<br>Set<String> set &#x3D; new HashSet&lt;&gt;(list);</p>
<p>使用Java 8的Stream API: 利用Stream的distinct()方法可以对List集合进行去重。可以使用以下代码：</p>
<p>List<String> list &#x3D; new ArrayList&lt;&gt;();<br>&#x2F;&#x2F; 添加元素到list…<br>List<String> distinctList &#x3D; list.stream().distinct().collect(Collectors.toList());</p>
<p>使用Apache Commons Collections库: 使用Apache Commons Collections库中的类SetUniqueList可以对List集合进行去重，并保持原始的元素顺序。可以使用以下代码：</p>
<p>List<String> list &#x3D; new ArrayList&lt;&gt;();<br>&#x2F;&#x2F; 添加元素到list…<br>List<String> distinctList &#x3D; SetUniqueList.setUniqueList(list);</p>
<p>使用LinkedHashSet保持顺序: 利用LinkedHashSet的特性，它保留元素的插入顺序并自动去重。可以使用以下代码：</p>
<p>List<String> list &#x3D; new ArrayList&lt;&gt;();<br>&#x2F;&#x2F; 添加元素到list…<br>Set<String> set &#x3D; new LinkedHashSet&lt;&gt;(list);<br>List<String> distinctList &#x3D; new ArrayList&lt;&gt;(set);</p>
<p>这些方法可以根据具体的需求和使用场景选择适合的方式进行List集合的去重操作。</p>
<p>（3）.数组和链表分别使用于什么场景，为什么？⭐⭐⭐<br>我的认识：<br>数据用于数据固定，不会轻易增删操作时，并且需要较高的查询效率，和比较低的内存消耗<br>链表用于数据不固定，需要经常进行增删操作，但是不需要经常查询时，对内存消耗要求不重要时</p>
<p>搜集资料：<br>数组和链表都是常用的数据结构，在不同的场景中适用性也有所不同。<br>适用于数组的场景：</p>
<p>需要随机访问元素：由于数组在内存中是连续存储的，通过索引可以直接访问任意元素，因此在需要频繁进行随机访问的场景下，数组更高效。<br>元素数量固定：数组在创建时需要指定大小，且大小固定，适用于元素数量已知且不会频繁变动的场景。<br>空间效率要求高：相对于链表，数组在存储元素时不需要额外的指针，因此在空间效率要求高的场景下，数组更适用。</p>
<p>适用于链表的场景：</p>
<p>频繁插入和删除操作：链表在插入和删除元素时只需要调整指针，不需要移动其他元素，因此在频繁进行插入和删除操作的场景下，链表更高效。<br>元素数量不固定：链表的大小可以根据需要动态调整，适用于元素数量经常变动的场景。<br>空间效率相对较低：链表每个节点需要额外的指针来指向下一个节点，相对于数组需要更多的内存空间，因此在空间效率要求相对较低的场景下，链表更适用。</p>
<p>需要根据具体的需求和使用场景来选择合适的数据结构，有时也可以结合使用数组和链表来充分发挥它们各自的优势。</p>
<p>（4）.ArrayList和LinkedList的底层数据结构是什么？⭐⭐⭐<br>我的认识：<br>ArrayList的底层时数组实现的，而LinkedList时双向链表实现的</p>
<h2 id="1-1-2-Queue"><a href="#1-1-2-Queue" class="headerlink" title="1.1.2 Queue"></a>1.1.2 Queue</h2><p>Queue是队列结构，常用于需要按顺序执行的任务。比如消息的传递。</p>
<h2 id="1-1-3-Set-不可重复"><a href="#1-1-3-Set-不可重复" class="headerlink" title="1.1.3 Set 不可重复"></a>1.1.3 Set 不可重复</h2><p>1.HashSet：HashMap实现，无序<br>2.TreeSet：二叉树实现<br>3.LinkedHashSet：继承HashSet，通过HashMap实现数据存储，双向链表记录顺序</p>
<h3 id="相关面试题-1"><a href="#相关面试题-1" class="headerlink" title="相关面试题"></a>相关面试题</h3><p>（1）.Set如何保证元素不重复？⭐⭐⭐<br>我的认识：<br>是通过HashCode计算得到哈希值，然后再利用equals比较。<br>搜集资料：<br>唯一性检查：当你尝试向 Set 添加一个元素时，它会首先检查该元素是否已经存在于集合中。如果是重复的元素，Set 将会忽略这个添加操作，保证集合中不存在重复元素。<br>哈希算法：Set 使用哈希算法来存储元素并进行快速访问。哈希算法将每个元素映射到一个唯一的哈希值，并将其用作元素的标识符。当你尝试查找集合中是否存在某个元素时，Set使用哈希算法来快速找到对应的哈希值，并检查该哈希值是否存在于集合中。</p>
<p>（2）.HashSet的原理是什么？⭐⭐<br>我的认识：通过HashMap实现<br>搜集资料：<br>哈希函数：HashSet 使用哈希函数将对象映射到哈希表的桶（bucket）中。哈希函数计算对象的哈希码（hashcode），它是一个整数值。每个对象都有一个对应的哈希码。<br>桶数组：HashSet 内部维护一个桶数组，每个桶可以存储一个或多个元素。桶数组的初始大小是固定的，根据负载因子（load factor）进行扩容。<br>桶的选择：通过哈希函数计算的哈希码确定了元素应该存储在哪个桶中。不同的元素可能会计算得到相同的哈希码，这就是哈希冲突（hash collision）。<br>链表或红黑树：当多个元素计算得到相同的哈希码时，它们被存储在同一个桶中，并以链表或红黑树的形式组织起来。这样相同哈希码的元素就可以在同一个桶中高效地查找和存取。<br>查找和插入：当需要查找一个元素时，HashSet首先计算元素的哈希码，然后根据哈希码找到对应的桶。如果桶中有多个元素，它们会被遍历以寻找目标元素。在插入一个新元素时，HashSet会计算元素的哈希码，确定应该存储在哪个桶中，并将元素添加到桶中。<br>哈希表的扩容：当 HashSet的大小超过负载因子乘以桶数组的长度时，就会触发扩容操作。扩容会创建一个更大的桶数组，并将所有的元素重新分配到新的桶中，以减少哈希冲突的可能性。</p>
<p>通过哈希函数和桶数组的组合，HashSet可以快速定位和访问元素，使得元素的查找和插入操作具有较高的效率。同时，哈希表的平均查找时间复杂度为 O(1)，在大多数情况下可以提供良好的性能。</p>
<p>（3）.TreeSet在排序时是如何比较元素的？⭐⭐<br>我的认识：按照指定顺序，升序或者降序。Integer和String有默认的排序方式。自定义的类型，需要通过覆写compareTo函数（有规则）来实现排序</p>
<p>搜集资料：<br>TreeSet 是 Java 中的一个有序集合类，它基于红黑树数据结构实现。在 TreeSet 中，元素的排序是通过比较器（Comparator）或元素的自然顺序（Natural Ordering）来完成的。</p>
<p>使用比较器：当创建 TreeSet时，你可以提供一个实现了Comparator接口的比较器对象。比较器定义了元素之间的比较规则。在插入元素时，TreeSet 会使用比较器来决定元素的位置。在进行比较时，会调用比较器的 compare 方法。<br>使用自然顺序：如果没有提供比较器，则TreeSet会使用元素的自然顺序来进行排序。要使用自然顺序，元素的类必须实现 Comparable 接口，并重写 compareTo 方法。在插入元素时，TreeSet 会调用元素的 compareTo 方法来进行比较。</p>
<p>在比较元素时，TreeSet 遵循以下规则：</p>
<p>如果比较结果为负数，表示第一个元素小于第二个元素。<br>如果比较结果为零，表示两个元素相等。<br>如果比较结果为正数，表示第一个元素大于第二个元素。</p>
<p>根据比较结果，TreeSet 决定元素在红黑树中的位置。这样就可以保持集合中的元素有序。<br>需要注意的是，当元素被插入到 TreeSet 中时，元素必须是可比较的，否则会抛出 ClassCastException 异常。如果使用比较器进行排序，则比较器负责处理元素之间的比较逻辑。</p>
<p>例如</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">public class YourClass implements Comparable&lt;YourClass&gt; &#123;</span><br><span class="line">    // 类的其他成员和方法</span><br><span class="line">    </span><br><span class="line">    @Override</span><br><span class="line">    public int compareTo(YourClass other) &#123;</span><br><span class="line">        // 实现compareTo方法</span><br><span class="line">        if (this.对象小于指定对象的条件) &#123;</span><br><span class="line">            return -1;</span><br><span class="line">        &#125; else if (this.对象等于指定对象的条件) &#123;</span><br><span class="line">            return 0;</span><br><span class="line">        &#125; else &#123;</span><br><span class="line">            return 1;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="1-1-4-Map"><a href="#1-1-4-Map" class="headerlink" title="1.1.4 Map"></a>1.1.4 Map</h2><p>1.HashMap：数组+链表存储数据，线程不安全<br>2.ConcurrentHashMap<br>3.HashTable：线程安全<br>4.TreeMap：基于二叉树数据结构<br>5.LinkedHashMap：继承HashMap，使用链表保存插入顺序</p>
<h3 id="相关面试题-2"><a href="#相关面试题-2" class="headerlink" title="相关面试题"></a>相关面试题</h3><p>（1）.HashMap是如何快速定位到数据的？⭐⭐⭐<br>HashMap 是 Java 中的一个哈希表实现，它可以提供快速的数据定位和访问。HashMap的快速定位是通过以下几个步骤实现的：<br>哈希函数：HashMap 使用哈希函数将键对象映射到一个整数值，这个整数值被称为哈希码（hashcode）。哈希函数的设计目标是尽量使得不同的键对象计算得到不同的哈希码，减少哈希冲突的可能性。</p>
<p>桶数组：HashMap 内部维护一个桶数组，桶数组的每个位置称为一个桶（bucket）。桶数组的长度是固定的，根据负载因子（load factor）进行扩容。</p>
<p>桶的选择：通过哈希函数计算键对象的哈希码，确定了键对象应该存储在哪个桶中。</p>
<p>链表或红黑树：由于不同的键对象可能计算得到相同的哈希码，这就是哈希冲突。当多个键对象计算得到相同的哈希码时，它们被存储在同一个桶中，并以链表或红黑树的形式组织起来。这样相同哈希码的键对象就可以在同一个桶中高效地查找和存取。</p>
<p>定位数据：当需要访问一个键对象时，HashMap首先计算键对象的哈希码，然后根据哈希码找到对应的桶。如果桶中有多个键对象，会遍历桶中的元素以找到目标键对象。</p>
<p>通过哈希函数和桶数组的结合，HashMap 可以快速定位到数据。在理想情况下，哈希函数将键对象均匀地分布在桶数组中，使得每个桶中的键对象数量保持较小的平均值。这样就可以在常数时间（O(1)）内定位到数据，提供高效的访问性能。当然，如果哈希冲突较多，链表或红黑树的查找操作可能会需要较长的时间。为了减少冲突，HashMap会自动进行扩容操作，以保持较低的负载因子和较小的哈希冲突概率。</p>
<p>（2）.ConcurrentHashMap是如何保障线程安全的？⭐⭐⭐<br>在JDK1.7中是通过Segment分段锁。分段锁（Segment-level-locking）：ConcurrentHashMap内部将哈希表分成了多个段（Segment），每个段都有一个独立的锁来保护其中的元素。不同的线程可以同时访问不同的段，从而提高并发性能。这样，在大多数情况下，只有访问同一个段的线程之间需要竞争锁。</p>
<p>在JDK1.8中弃用了Segment分段锁，改用Synchronized+CAS实现对多线程的安全操作。同时引入了红黑树<br>无阻塞算法：ConcurrentHashMap 内部使用一种无阻塞的算法（CAS，Compare-and-Swap）来实现线程安全。这种算法可以在没有锁的情况下进行并发更新，提高了并发性能。<br>红黑树：ConcurrentHashMap 在某些情况下会将链表转换为红黑树，以提高搜索、插入和删除元素的效率。红黑树的操作是基于节点的，而不是对整个数据结构的操作，因此可以减小锁的粒度，提高并发性能。</p>
<p>（3）.常用的Map集合有哪些？⭐⭐<br>HashMap、TreeMap、LinkedHashMap、ConcurrentHashMap、Hashtable</p>
<p>（4）.HashMap是线程安全的吗？⭐⭐<br>不是</p>
<p>（5）.HashMap的内部数据结构是什么？⭐⭐<br> HashMap 的内部数据结构是一个使用链表和红黑树的数组，用来存储键值对。通过哈希函数和数组索引，HashMap 可以快速定位到元素所在的桶，并在桶内进行元素的查找、插入和删除操作。</p>
<p>（6）.HashMap在JDK1.8中引入红黑树可以带来什么好处？⭐⭐</p>
<p>在 JDK 1.8 中，HashMap 引入了红黑树作为解决哈希冲突的一种方式，相较于链表，红黑树可以带来以下好处：</p>
<p>提高性能：当哈希冲突较多时，链表的查找、插入和删除操作的时间复杂度为 O(n)，其中 n 是链表中元素的数量。而红黑树的这些操作的时间复杂度为 O(log n)，相对较低。因此，使用红黑树可以在哈希冲突较多时提供更好的性能。</p>
<p>平衡性：红黑树是一种自平衡的二叉搜索树，它在插入和删除元素时会自动调整树的结构，保持树的平衡性。这样可以避免出现极端情况下的链表退化，提高了操作的可靠性和一致性。</p>
<p>减少查找时间：在红黑树中，查找操作的平均时间复杂度为 O(log n)，相对于链表的 O(n) 进行了明显的优化。这对于大型的 HashMap，其中桶中有大量元素的情况下，可以加快查找元素的速度。</p>
<p>需要注意的是，并不是所有的哈希冲突都会转换成红黑树。只有当链表中的元素数量超过一个阈值（默认为8）时，链表才会自动转换为红黑树。这是为了避免在元素较少时引入红黑树的额外开销。<br>总结起来，HashMap 在 JDK 1.8 中引入红黑树作为解决哈希冲突的一种方式，以提高性能、平衡性和查找速度。</p>
<p>（7）.HashMap和HashTable的区别是什么？⭐⭐<br>线程安全性：HashTable是线程安全的，它的方法在内部进行同步处理，因此多个线程可以同时访问HashTable。而HashMap是非线程安全的，如果多个线程同时访问一个HashMap并且至少一个线程修改了HashMap的结构，那么必须通过外部同步来确保线程安全。</p>
<p>Null值：HashMap允许键和值都为null，而HashTable则不允许，会抛出NullPointerException。</p>
<p>迭代器：HashMap的迭代器是fail-fast的，即如果在迭代过程中HashMap的结构被修改，会抛出ConcurrentModificationException异常。而HashTable的迭代器不是fail-fast的。</p>
<p>继承关系：HashTable是基于Dictionary类的旧实现，而HashMap是基于AbstractMap类的新实现。由于继承关系的差异，HashMap可以提供更多的灵活性和功能扩展。</p>
<h1 id="1-2-异常的分类及处理"><a href="#1-2-异常的分类及处理" class="headerlink" title="1.2 异常的分类及处理"></a>1.2 异常的分类及处理</h1><h2 id="1-2-1-异常的概念"><a href="#1-2-1-异常的概念" class="headerlink" title="1.2.1 异常的概念"></a>1.2.1 异常的概念</h2><p>异常指在方法不能按照正常方式完成时，可以通过抛出异常的方法退出该方法。在异常中封装了方法执行过程中的错误信息及原因，调用方在获取该异常后可根据业务情况选择处理该异常或者继续抛出该异常。</p>
<p>在方法执行过程中出现异常时，Java异常处理机制会将代码的执行权交给异常处理器，异常处理器选择抛出异常或者捕捉并处理异常</p>
<h2 id="1-2-2-异常的分类"><a href="#1-2-2-异常的分类" class="headerlink" title="1.2.2 异常的分类"></a>1.2.2 异常的分类</h2><p>在Java中，Throwable是所有错误或异常的父类</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">flowchart TB</span><br><span class="line">    object --&gt; Throwable --&gt; Exception --&gt; RuntimeExpection-运行时异常</span><br><span class="line">    Exception --&gt; CheckedException-检查异常</span><br><span class="line">    Throwable --&gt; Error --&gt; AWTError</span><br><span class="line">    Error --&gt;ThreadDeath</span><br></pre></td></tr></table></figure>

<p>Error指Java程序运行错误，启动时会启动失败，运行时会退出进程。通常是因为系统内部错误或资源耗尽（不能在运行中被动态处理），只能记录错误的成因和安全终止</p>
<p>Exception指Java程序运行异常，可被Java异常处理机制处理。是程序开发中异常处理的核心。<br>RuntimeException一定是程序发生错误导致的，需要抛出异常或者捕捉处理该异常<br>CheckedException一般由于打开错误的文件、SQL语法错误，类不存在等引起的 通过 try catch 处理异常</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">flowchart TB</span><br><span class="line">    Exception --&gt; RuntimeException --&gt; NullPointerException</span><br><span class="line">    RuntimeException --&gt; ClassCastException</span><br><span class="line">    RuntimeException --&gt; ArrayIndexOutOfBundsException</span><br><span class="line"></span><br><span class="line">    Exception --&gt; CheckedException --&gt; SQLException</span><br><span class="line">    CheckedException --&gt; IOException</span><br><span class="line">    CheckedException --&gt; ClassNotFoundException</span><br></pre></td></tr></table></figure>

<h2 id="1-2-3-处理异常的方式"><a href="#1-2-3-处理异常的方式" class="headerlink" title="1.2.3 处理异常的方式"></a>1.2.3 处理异常的方式</h2><p>（1）.抛出异常<br>throw：作用在方法内，后面跟着的是异常的对象，用于抛出封装了异常信息的对象，throw后面的语句块无法被执行（finall语句块除外）<br>throws：作用在方法上，后面跟着的是异常的类，用于声明方法在运行过程中可能出现的异常，以便调用者根据不同的异常类型预先定义不同的处理方式</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">throw</span><br><span class="line"></span><br><span class="line">public static void main(String[] args)&#123;</span><br><span class="line">    String str = &quot;hello offer&quot;;</span><br><span class="line">    int index = 10;</span><br><span class="line">    if(index &gt;= str.length())&#123;</span><br><span class="line">        //1.使用throw在方法内抛出异常</span><br><span class="line">        throw new StringIndexOutOfBundsException();</span><br><span class="line">    &#125;else&#123;</span><br><span class="line">        str.substring(0,index);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">throws</span><br><span class="line"></span><br><span class="line">int div(int a,int b) throws Exception&#123;</span><br><span class="line">    return a/b</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>（2）.使用 try catch语句块捕获并处理异常<br>    使用 try catch语句块捕获并处理异常能够有针对性地处理每种可能出现的异常，并在捕获到异常后根据不同情况做不同的处理,用法如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">try &#123;</span><br><span class="line">    //具体的业务逻辑实现</span><br><span class="line">    &#125;catch（Exception e）&#123;</span><br><span class="line">    //捕获异常并处理</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="相关面试题-3"><a href="#相关面试题-3" class="headerlink" title="相关面试题"></a>相关面试题</h3><p>（1）.Java中的异常处理方式（机制）有哪些？⭐⭐⭐<br>try-catch语句块、throws声明、自定义异常</p>
<p>（2）.Error和Exception的区别是什么？⭐⭐<br>Error表示严重的问题，无法被程序员捕获和处理，而Exception表示可以预料到的异常情况，可以通过异常处理机制进行捕获和处理。<br>在实际开发中，应该对Exception进行适当的处理，以确保程序的可靠性和稳定性。对于Error，一般不建议进行主动处理，而是让虚拟机进行相应的处理</p>
<p>（3）.throw和throws的具体区别是什么？⭐<br>throw用于抛出具体的异常对象，而throws用于声明方法可能抛出的异常类型。</p>
<p>throw关键字可以在方法内部使用，用于手动触发异常，而throws关键字只能在方法签名中使用。</p>
<p>throw抛出的异常由程序员主动控制，而throws声明的异常是方法可能抛出的异常，由调用者处理。</p>
<h1 id="1-3-反射机制"><a href="#1-3-反射机制" class="headerlink" title="1.3 反射机制"></a>1.3 反射机制</h1><h2 id="1-3-1-动态语言的概念"><a href="#1-3-1-动态语言的概念" class="headerlink" title="1.3.1 动态语言的概念"></a>1.3.1 动态语言的概念</h2><p>动态语言指程序运行时可以改变其结构的语言，比如JS，而Java属于半动态语言，C、C++不属于动态语言</p>
<h2 id="1-3-2-反射机制的概念"><a href="#1-3-2-反射机制的概念" class="headerlink" title="1.3.2 反射机制的概念"></a>1.3.2 反射机制的概念</h2><p>反射机制指在程序运行过程中，对任意一个类都能获取其所有属性和方法，并且对任意对象都能调用其任意方法。<br>动态取类和对象的信息，以及动态调用对象的方法的功能被称为Java的反射机制</p>
<h2 id="1-3-3-反射的应用"><a href="#1-3-3-反射的应用" class="headerlink" title="1.3.3 反射的应用"></a>1.3.3 反射的应用</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">flowchart LR</span><br><span class="line">    Java对象 --&gt; 编译时类型-声明对象时的类型</span><br><span class="line">    Java对象 --&gt; 运行时类型</span><br></pre></td></tr></table></figure>
<p>例如<br><code> Person person = new Student();</code><br>person对象的编译时类型为Person，运行时类型为Student<br>因此，程序在编译期间无法预知该对象和类的真是信息，只能通过运行时信息来发现该对象和类的真实信息，而其真实信息（对象的属性和方法）通常通过反射机制来获取，这便是Java中反射机制的 <strong>核心功能</strong></p>
<h2 id="1-3-4-Java的反射API"><a href="#1-3-4-Java的反射API" class="headerlink" title="1.3.4 Java的反射API"></a>1.3.4 Java的反射API</h2><p>Java的反射API主要用于在运行过程中动态生成类、接口或对象等信息，其常用API如下。<br>Class类：用于获取类的属性、方法等信息。<br>Field类：表示类的成员变量，用于获取和设置类中的属性值。<br>Method类：表示类的方法、用于获取方法的描述信息或者执行某个方法。<br>Constructor类：表示类的构造方法</p>
<h2 id="1-3-5-反射的过程"><a href="#1-3-5-反射的过程" class="headerlink" title="1.3.5 反射的过程"></a>1.3.5 反射的过程</h2><p>步骤：<br>    （1）.获取想要操作的类的Class对象，该Class对象是反射的核心，通过它可以调用类的任意方法。<br>    （2）.调用Class对象所对应的类中定义的方法，这是反射的使用阶段。<br>    （3）.使用反射API来获取并调用类的属性和方法等信息。<br>获取Class对象的3种方式：<br>    （1）.调用某个对象的getClass方法以获取该类对应的Class对象：<br>            Person p &#x3D; new Person();<br>            Class c &#x3D; p.getClass();<br>    （2）.调用某个类的class属性以获取该类对应的Class对象：<br>            Class c &#x3D; Person.class;<br>    （3）.调用Class类中的forName静态方法以获取该类对应的Class对象，这是最安全、性能也最好的方式：<br>            Class c &#x3D; Class.forName(“fullClassPath”); &#x2F;&#x2F;fullClassPath为类的包路径及名称</p>
<h2 id="1-3-6-创建对象的两种方式"><a href="#1-3-6-创建对象的两种方式" class="headerlink" title="1.3.6 创建对象的两种方式"></a>1.3.6 创建对象的两种方式</h2><p>以创建对象的具体代码举例：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">//1.1：获取Person类的Class对象</span><br><span class="line">Class c = Class.forName(&quot;fullClassPath&quot;);</span><br><span class="line">//1.2：使用newInstance方法创建对象，----这种方式要求该Class对象对应的类有默认的空构造器</span><br><span class="line">Person p = (Person) c.newInstance();</span><br><span class="line">//2.1：获取构造方法并创建对象</span><br><span class="line">Constructor con = c.getDeclaredConstructor(String.class,String.class,int.class);</span><br><span class="line">//2.2：根据构造方法创建对象并设置属性</span><br><span class="line">Person p1 = (Person) con.newInstance(&quot;李四&quot;,&quot;男&quot;,&quot;20&quot;);</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="1-3-7-Method的invoke方法"><a href="#1-3-7-Method的invoke方法" class="headerlink" title="1.3.7 Method的invoke方法"></a>1.3.7 Method的invoke方法</h2><p>通过invoke方法可以实现动态调用，比如可以动态传入参数并将方法参数化。具体过程：获取Method对象，并调用Method的invode方法。<br>（1）.获取Method对象：通过调用Class对象的 getMethod(String name, Class&lt;?&gt;… parameterTypes)返回一个Method对象，它描述了此Class对象所表示的类或接口指定的公共成员方法。name参数是String类型，用于指定所需方法的名称。parameterTypes参数是按声明顺序标识该方法的参数类型的Class对象的一个数组，如果parameterTypes为null，则按空数组处理。<br>（2）.调用Method的invoke方法：通过调用Method对象的invoke方法来动态执行函数。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">invoke方法的具体使用代码如下：</span><br><span class="line">//1：获取Persion类(hello.java.reflect.Persion) 的Class对象</span><br><span class="line">Class clz = Class.forName(&quot;hello.java.reflect.Persion&quot;);</span><br><span class="line">//2：获取Class对象中的setName方法</span><br><span class="line">Method method = clz.getMethod(&quot;setName&quot;,String.class);</span><br><span class="line">//3：获取Constructor对象</span><br><span class="line">Constructor constructor = clz.getConstructor();</span><br><span class="line">//4：根据Constructor定义对象</span><br><span class="line">Object object = constructor.newInstance();</span><br><span class="line">//5：调用Method的invoke方法，这里的Method表示setName方法</span><br><span class="line">//因此，相当于动态调用object对象的setName方法并传入alex参数</span><br><span class="line">method.invoke(object,&quot;alex&quot;);</span><br></pre></td></tr></table></figure>

<h3 id="相关面试题-4"><a href="#相关面试题-4" class="headerlink" title="相关面试题"></a>相关面试题</h3><p>（1）.Java反射机制的作用是什么？⭐⭐⭐<br>Java反射机制是指在运行时动态地获取类的信息并操作类的成员（字段、方法、构造器等）的能力。它提供了一种机制，使得程序可以在运行时检查和获取类的成员信息，而不需要在编译时就确定。</p>
<p>反射机制的主要作用如下：</p>
<p>动态加载类：通过反射机制，可以在运行时动态地加载类，而不需要在编译时就确定类的名称。这使得程序更加灵活，可以根据需要动态地加载和使用不同的类。</p>
<p>获取类的信息：通过反射，可以在运行时获取类的各种信息，如类的名称、父类、接口、字段、方法、构造器等。这使得程序可以在运行时动态地了解和操作类的结构。</p>
<p>创建对象：反射机制可以在运行时动态地创建类的对象，即使在编译时并不知道类的具体名称。通过获取类的构造器信息，可以实例化对象并调用相应的方法。</p>
<p>调用方法和访问字段：通过反射，可以在运行时动态地调用类的方法和访问字段。可以通过获取方法和字段的信息，并通过反射调用相应的方法和访问字段的值，从而实现对类的灵活操作。</p>
<p>扩展应用框架：反射机制广泛应用于许多框架和库，如ORM（对象关系映射）框架、依赖注入框架、动态代理等。反射机制使得这些框架可以在运行时动态地操作和管理对象。</p>
<p>需要注意的是，虽然反射机制提供了一种强大的能力，但它也带来了一定的性能开销。在不需要动态操作类的情况下，建议尽量避免使用反射，以提高程序的性能和可读性。</p>
<p>（2）.Java反射机制创建对象的方式有哪些？⭐⭐</p>
<p>1.使用Class类的newInstance方法：Class类提供了一个名为newInstance()的方法，用于创建类的实例。这个方法要求被创建的类必须具有无参构造方法，并且是可访问的。</p>
<p>Class&lt;?&gt; clazz &#x3D; MyClass.class;<br>MyClass obj &#x3D; (MyClass) clazz.newInstance();</p>
<p>2.使用Constructor类的newInstance方法：Constructor类提供了一个名为newInstance()的方法，用于通过构造器创建对象。这种方式可以传递参数给构造器，可以创建有参构造方法的实例。</p>
<p>Constructor<MyClass> constructor &#x3D; MyClass.class.getConstructor(String.class, int.class);<br>MyClass obj &#x3D; constructor.newInstance(“example”, 10);</p>
<p>3.使用Constructor类的newInstance方法（无参构造器）：如果要创建对象的类只有无参构造器，可以直接使用Constructor类的newInstance()方法，无需传递参数。</p>
<p>Constructor<MyClass> constructor &#x3D; MyClass.class.getConstructor();<br>MyClass obj &#x3D; constructor.newInstance();</p>
<p>4.使用Object类的clone方法：如果对象实现了Cloneable接口，可以使用clone()方法来复制对象。在这种情况下，会调用对象的无参构造器来创建新的对象。</p>
<p>MyClass obj1 &#x3D; new MyClass();<br>MyClass obj2 &#x3D; (MyClass) obj1.clone();</p>
<p>需要注意的是，使用反射创建对象时，要确保所需的构造器是可访问的（包括无参构造器和有参构造器）。如果构造器是私有的或受保护的，可以在调用构造器前使用setAccessible(true)方法来设置可访问性。<br>Constructor<MyClass> constructor &#x3D; MyClass.class.getDeclaredConstructor();<br>constructor.setAccessible(true);<br>MyClass obj &#x3D; constructor.newInstance();</p>
<p>以上是常见的反射创建对象的方式，具体使用哪种方式取决于类的构造器和使用场景。</p>
<p>（3）.Java是如何实现动态调用某个方法的？⭐⭐</p>
<p>Java通过反射机制实现动态调用某个方法。反射机制提供了一组用于查询和操作类、方法和字段的API，通过这些API，可以在运行时动态地获取和调用类的方法。</p>
<p>以下是通过反射实现动态调用方法的一般步骤：</p>
<p>1.获取类的Class对象：首先需要获取表示目标类的Class对象，可以使用Class.forName()方法传入类的全限定名来获取，或者使用obj.getClass()方法获取已有对象的Class对象。</p>
<p>Class&lt;?&gt; clazz &#x3D; Class.forName(“com.example.MyClass”);</p>
<p>2.获取方法对象：通过Class对象的getMethod()或getDeclaredMethod()方法获取目标方法的Method对象。getMethod()方法可以获取公共方法（包括父类的公共方法），而getDeclaredMethod()方法可以获取本类中声明的所有方法（包括私有方法）。</p>
<p>Method method &#x3D; clazz.getMethod(“methodName”, parameterTypes);</p>
<p>3.调用方法：通过Method对象的invoke()方法来调用目标方法。invoke()方法可以接受一个对象实例作为调用者，并传递所需的参数。如果目标方法是静态方法，则调用时可以将实例对象设置为null。</p>
<p>Object result &#x3D; method.invoke(obj, args);</p>
<p>需要注意的是，通过反射调用方法可能会引发一些异常，如NoSuchMethodException、IllegalAccessException、InvocationTargetException等。因此，在使用反射调用方法时，需要适当地处理这些异常。<br>通过反射实现动态调用方法可以让程序在运行时动态地确定要调用的方法，并传递适当的参数。这在某些情况下非常有用，比如插件化开发、框架扩展等。但是，由于反射调用的开销相对较高，应该在必要时使用，并注意处理异常和性能问题。</p>
<p>（4）.通过Java反射创建对象和通过new创建对象，哪个效率更高？⭐</p>
<p>通过new关键字创建对象的效率通常比通过Java反射创建对象的效率更高。</p>
<p>使用new关键字创建对象时，编译器在编译时就已经确定了要创建的对象的类型，并且直接调用相应的构造器进行对象的初始化。这种方式避免了在运行时通过反射获取构造器的开销，使得对象的创建过程更加高效。</p>
<p>而通过Java反射创建对象时，需要在运行时通过反射机制获取构造器，并调用构造器进行对象的初始化。这涉及到额外的反射操作和动态方法调用，会引入一定的性能开销。</p>
<p>由于反射机制的灵活性和动态性，它在某些特定场景下是非常有用的，如框架和工具的开发。但在一般情况下，如果已知对象的具体类型并且不需要动态性的话，直接使用new关键字创建对象更加高效。<br>需要注意的是，对于对象的初始化过程，无论是通过new关键字还是通过反射创建对象，实际上都会调用到构造器进行初始化。因此，构造器的执行过程对于对象的创建效率也有一定的影响。在需要频繁创建对象的性能敏感场景中，可以考虑使用对象池等技术来减少对象的创建和销毁开销。</p>
<p>（5）.除了可以使用new方法创建对象，还可以使用什么方法创建对象？⭐<br>1.使用Class对象的newInstance方法创建该Class对象。<br>2.使用Class对象获取指定的Constructor对象，再调用Constructor对象的newInstance方法创建Class对象对应类的实例</p>
<h1 id="1-4-注解"><a href="#1-4-注解" class="headerlink" title="1.4 注解"></a>1.4 注解</h1><h2 id="1-4-1-注解的概念"><a href="#1-4-1-注解的概念" class="headerlink" title="1.4.1 注解的概念"></a>1.4.1 注解的概念</h2><h2 id="1-4-2-标准元注解：-Target、-Retention、-Documented、-Inherited"><a href="#1-4-2-标准元注解：-Target、-Retention、-Documented、-Inherited" class="headerlink" title="1.4.2 标准元注解：@Target、@Retention、@Documented、@Inherited"></a>1.4.2 标准元注解：@Target、@Retention、@Documented、@Inherited</h2><h2 id="1-4-3-注解处理器"><a href="#1-4-3-注解处理器" class="headerlink" title="1.4.3 注解处理器"></a>1.4.3 注解处理器</h2><h3 id="相关面试题-5"><a href="#相关面试题-5" class="headerlink" title="相关面试题"></a>相关面试题</h3>
</article>
    
    <div class="trm-reward">
        
            <span class="trm-reward-btn trm-glow" onclick='var qr = document.getElementById("qr"); qr.style.display = (qr.style.display === "none") ? "block" : "none";'>
                <i class="iconfont fas fa-hand-holding-usd"></i>
            </span>
        
        <p class="trm-reward-comment">I'm so cute. Please give me money.</p>
        <div id="qr" style="display:none;">
            
                <div style="display:inline-block">
                    <a rel="noopener noreferrer" href='\img\QRCode.jpg' target='_blank' >
                       <img src="/myblog/%5Cimg%5CQRCode.jpg" alt="微信" loading="lazy">
                    </a>
                    <p>微信</p>
                </div>
            
                <div style="display:inline-block">
                    <a rel="noopener noreferrer" href='\img\Alipay.jpg' target='_blank' >
                       <img src="/myblog/%5Cimg%5CAlipay.jpg" alt="支付宝" loading="lazy">
                    </a>
                    <p>支付宝</p>
                </div>
            
        </div>
    </div>

    

</div>
<div id="post-next-prev" class="row">
    <div class="col-lg-12">
        <!-- title -->
        <h5 class="trm-title-with-divider">
            其他文章
            <span data-number="02"></span>
        </h5>
    </div>
    
        <div class="col-lg-6">
    <div class="trm-blog-card trm-scroll-animation" data-scroll data-scroll-offset="40">
        <a href="/myblog/2023/11/25/SSM%E6%95%B4%E5%90%88/" class="trm-cover-frame trm-anima-link">
            
            
                <img alt="cover" class="no-fancybox" src="/myblog/img/block.jpg">
            
        </a>
        
        <div class="trm-card-descr">
            <div class="trm-label trm-category trm-mb-20">
                <a href=" /myblog/categories/SSM%E9%A1%B9%E7%9B%AE%E6%95%B4%E5%90%88/">
                    SSM项目整合
                </a>
            </div>
            <h5>
                <a href="/myblog/2023/11/25/SSM%E6%95%B4%E5%90%88/" class="trm-anima-link">
                    学会整合SSM
                </a>
            </h5>
            <div class="trm-divider trm-mb-20 trm-mt-20"></div>
            <ul class="trm-card-data trm-label">
                <li>23/11/25</li>
                <li>17:57</li>
                
                
            </ul>
        </div>
    </div>
</div>
    
    
        <div class="col-lg-6">
    <div class="trm-blog-card trm-scroll-animation" data-scroll data-scroll-offset="40">
        <a href="/myblog/2023/07/28/%E5%89%8D%E7%AB%AF%E6%A1%86%E6%9E%B60%E5%9F%BA%E7%A1%80%E6%90%AD%E5%BB%BA/" class="trm-cover-frame trm-anima-link">
            
            
                <img alt="cover" class="no-fancybox" src="/myblog/img/block.jpg">
            
        </a>
        
        <div class="trm-card-descr">
            <div class="trm-label trm-category trm-mb-20">
                <a href=" /myblog/categories/learn-and-imitate/">
                    learn and imitate
                </a>
            </div>
            <h5>
                <a href="/myblog/2023/07/28/%E5%89%8D%E7%AB%AF%E6%A1%86%E6%9E%B60%E5%9F%BA%E7%A1%80%E6%90%AD%E5%BB%BA/" class="trm-anima-link">
                    前端框架搭建
                </a>
            </h5>
            <div class="trm-divider trm-mb-20 trm-mt-20"></div>
            <ul class="trm-card-data trm-label">
                <li>23/07/28</li>
                <li>07:34</li>
                
                
            </ul>
        </div>
    </div>
</div>
    
</div>

    



                    <div class="trm-divider footer-divider"></div>

                    <!-- footer -->
                    <footer class="trm-scroll-animation" data-scroll data-scroll-offset="50">

    
        <div class="trm-footer-item">
            <a rel="noopener" href="https://beian.miit.gov.cn/" target="_blank"></a>
        </div>
    

    

    
        <div class="trm-footer-item">
            <span>
                由 <a href="https://hexo.io" target="_blank" rel="noopener">Hexo</a> 驱动 v6.3.0
            </span>
            <span class="footer-separator" data-separator=" | "></span>
            <span> 
                主题 - 
                <a rel="noopener" href='https://github.com/MaLuns/hexo-theme-async' target='_blank'>Async</a>
                v2.0.9
            </span>
        </div>
      

    
        <div class="trm-footer-item">
            博客已萌萌哒运行 <span id="since" class="trm-accent-color"></span> 天
        </div>
     

    
        <div class="trm-footer-item">
            Hosted by <a href="https://github.com" rel="noopener" target="_blank">Github Pages</a>
        </div>
     
</footer>

<script>
    function show_date_time () {
        var BirthDay = new Date("07/15/2023 17:57:32");
        var today = new Date();
        var timeold = (today.getTime() - BirthDay.getTime());
        var msPerDay = 24 * 60 * 60 * 1000
        var day = Math.floor(timeold / msPerDay)
        since.innerHTML = day
    }
    show_date_time()
</script>
 
                    <!-- footer end -->

                </div>
            </div>
        </div>
    </div>
</div>
            <!-- body end -->

            <div class="trm-fixed-container" data-scroll data-scroll-sticky data-scroll-target=".locomotive-scroll__sticky-target" data-scroll-offset="-10">
    
        <div class="trm-fixed-btn" data-title="阅读模式" onclick="asyncFun.switchReadMode()">
            <i class="iconfont fas fa-book-reader"></i>
        </div>
    
    
    <div id="trm-back-top" class="trm-fixed-btn" data-title="回到顶部">
        <i class="iconfont fas fa-arrow-up"></i>
    </div>
</div>
          </div>
        </div>
      </div>
      <!-- scroll container end -->

  </div>
  <!-- app wrapper end -->

  
  <!-- Plugin -->




    
    
<script src="https://unpkg.com/locomotive-scroll@4.1.4/dist/locomotive-scroll.min.js"></script>

    
<script src="https://unpkg.com/@fancyapps/ui@4.0/dist/fancybox.umd.js"></script>

    

    
        <script src="/myblog/js/plugins/typing.js?v=2.0.9"></script>
    

    

    <!-- 数学公式 -->
    

    <!-- 评论插件 -->
    
        

        
    



<!-- CDN -->


    

    

    




    <!-- Service Worker -->
    
    <!-- baidu push -->
    


<script id="async-script" src="/myblog/js/main.js?v=2.0.9"></script>

</body>

</html>